#include "grenadeentity.h"

#include "application.h"
#include "serviceentity.h"
#include "graphics/graphicsmanager.h"

#include "graphics/texturemanager.h"
#include "graphics.opengl/texture.h"
#include "graphics/texture.h"

#include "servicecamera.h"
#include "serviceworld.h"

#include "worldgridmanager.h"
#include "helpers.h"
#include "graphics/renderer.h"

namespace infinity {

/*static*/ const dw::float32 GrenadeEntity::InfiniteTime = std::numeric_limits< dw::float32 >::infinity();

/*virtual*/ void GrenadeEntity::renderDebug()
{
	super::renderDebug();

	if (m_physicObject != NULL)
	{	
		dw::graphics::Renderer& renderer(dw::graphics::GraphicsManager::getInstance().getRenderer());
		const Matrix4f& objectMtx = m_physicObject->getTransform();

		renderer.pushState();

		renderer.setMatrixMode(dw::graphics::Renderer::MODELVIEW);
		renderer.pushMatrix();

		renderer.multMatrix(objectMtx);

		renderer.setRenderState(dw::graphics::Renderer::RS_DEPTH_TEST, true);
		renderer.setRenderState(dw::graphics::Renderer::RS_LIGHTING, false);
		renderer.setRenderState(dw::graphics::Renderer::RS_ALPHA_TEST, false);

		const WorldGridManager& worldManager = WorldGridManager::getInstance();

		{

			dw::graphics::ITexture* tex = dw::graphics::TextureManager::getInstance().getTexture("items.png");
			renderer.setTexture(tex);

			dw::maths::Vector2f upleft = dw::maths::Vector2f(14/16.0f,0.0f);
			float sizecell = 1/16.0f;


			glBegin(GL_QUADS);
			// Front Face
			glNormal3f( 0.0f, 1.0f, 0.0f);
			glTexCoord2f(upleft.x , upleft.y + sizecell); glVertex3f(0.2f, -0.2f,  0.2f);	// Bottom Left Of The Texture and Quad
			glTexCoord2f(upleft.x , upleft.y); glVertex3f( 0.2f, 0.2f,  0.2f);	// Bottom Right Of The Texture and Quad
			glTexCoord2f(upleft.x + sizecell, upleft.y ); glVertex3f( -0.2f,  0.2f, -0.2f);	// Top Left Of The Texture and Quad
			glTexCoord2f(upleft.x + sizecell, upleft.y + sizecell); glVertex3f( -0.2f, -0.2f, -0.2f);	// Bottom Left Of The Texture and Quad

			glTexCoord2f(upleft.x + sizecell, upleft.y + sizecell); glVertex3f( -0.2f, -0.2f, -0.2f);	// Bottom Left Of The Texture and Quad
			glTexCoord2f(upleft.x + sizecell, upleft.y ); glVertex3f( -0.2f,  0.2f, -0.2f);	// Top Left Of The Texture and Quad
			glTexCoord2f(upleft.x , upleft.y); glVertex3f( 0.2f, 0.2f,  0.2f);	// Bottom Right Of The Texture and Quad
			glTexCoord2f(upleft.x , upleft.y + sizecell); glVertex3f(0.2f, -0.2f,  0.2f);	// Bottom Left Of The Texture and Quad



			glTexCoord2f(upleft.x , upleft.y + sizecell); glVertex3f(-0.2f, -0.2f,  0.2f);	// Bottom Left Of The Texture and Quad
			glTexCoord2f(upleft.x , upleft.y); glVertex3f( -0.2f, 0.2f,  0.2f);	// Bottom Right Of The Texture and Quad
			glTexCoord2f(upleft.x + sizecell, upleft.y ); glVertex3f( 0.2f,  0.2f, -0.2f);	// Top Left Of The Texture and Quad
			glTexCoord2f(upleft.x + sizecell, upleft.y + sizecell); glVertex3f( 0.2f, -0.2f, -0.2f);	// Bottom Left Of The Texture and Quad

			glTexCoord2f(upleft.x + sizecell, upleft.y + sizecell); glVertex3f( 0.2f, -0.2f, -0.2f);	// Bottom Left Of The Texture and Quad
			glTexCoord2f(upleft.x + sizecell, upleft.y ); glVertex3f( 0.2f,  0.2f, -0.2f);	// Top Left Of The Texture and Quad
			glTexCoord2f(upleft.x , upleft.y); glVertex3f( -0.2f, 0.2f,  0.2f);	// Bottom Right Of The Texture and Quad
			glTexCoord2f(upleft.x , upleft.y + sizecell); glVertex3f(-0.2f, -0.2f,  0.2f);	// Bottom Left Of The Texture and Quad


			glEnd();

			
			renderer.popState();
			renderer.popMatrix();
		}
	}
}

/*virtual*/ GrenadeEntity::~GrenadeEntity()
{
}

/*virtual*/ Entity::State GrenadeEntity::onInitializeSimulation()
{
	State superState = super::onInitializeSimulation();

	if ( superState == State_Initialized )
	{
		dwAssert(m_physicObject == NULL, "Invalid internal state");
		m_physicObject = Application::getInstance().getService< ServicePhysics >().createObject();

		if (m_physicObject != NULL)
		{
			m_physicObject->setPosition(m_initialPosition);
			m_physicObject->applyImpulse(m_initialVelocity);
		}

		return (m_physicObject != NULL) ? State_Initialized : State_InitializationFailed;
	}

	return superState;
}

/*virtual*/ void GrenadeEntity::onUpdateSimulation(dw::float32 deltaT)
{
	super::onUpdateSimulation(deltaT);

	if (m_timeToLive != InfiniteTime)
	{
		m_timeToLive -= deltaT;

		if (m_timeToLive < 0.0f)
		{
			Application::getInstance().getService< ServiceEntity >().condemnEntity(this);
			WorldGridManager::getInstance().getPlanet()->boom(Helpers::positionToCell(Vector3f(getMatrix().pos)), 5, 5.25);
		}
	}
}

/*virtual*/ Entity::State GrenadeEntity::onTerminateSimulation()
{
	if (m_physicObject != NULL)
	{
		Application::getInstance().getService< ServicePhysics >().releaseObject(m_physicObject);
		m_physicObject = NULL;
	}

	return super::onTerminateSimulation();
}

/*virtual*/ Entity::State GrenadeEntity::onInitializeMedia()
{
	return super::onInitializeMedia();
}

/*virtual*/ void GrenadeEntity::onUpdateMedia(dw::float32 deltaT)
{
	super::onUpdateMedia(deltaT);
}

/*virtual*/ Entity::State GrenadeEntity::onTerminateMedia()
{
	return super::onTerminateMedia();
}

} // namespace infinity
